ggplot2(6)-描述数据分布

绘制简单直方图

1
2
library(ggplot2)
ggplot(faithful,aes(x=waiting)) + geom_histogram()

mark

快速建立直方图

可以将数据框参数设定为NULL,然后向其传递一个向量:

1
2
w <- faithful$waiting
ggplot(NULL,aes(x=w)) + geom_histogram()

mark

调节组距

默认的数据被分为30组,可以通过binwidth()参数才调节:

1
2
3
ggplot(faithful,aes(x=waiting)) +
geom_histogram(binwidth=5,fill="white",colour="black")
# 设定组距为5

mark

把数据分为15组,如下所示:

1
2
3
4
binsize <- diff(range(faithful$waiting))/15 # 把数据分为15组,diff()是差分函数,什么是差分,不懂
ggplot(faithful,aes(x=waiting))+
geom_histogram(binwidth=binsize,fill="white",colour="black")

mark

有时候,直方图的外观会非常依赖于组距及组边界。现在我们将组距离设为8,同时设定分组原点(origin)参数,令组边界分别位于31、39、47等,在第二张图中,对origin参数增加4,令组边界分别位于35、43、51等,如下所示:

1
2
h <- ggplot(faithful,aes(x=waiting))
h + geom_histogram(binwidth=8,fill="white",colour="black",boundary=31)

mark

1
2
h <- ggplot(faithful,aes(x=waiting))
h + geom_histogram(binwidth=8,fill="white",colour="black",boundary=35)

mark

基于分组数据绘制分组直方图

以MASS包中的birthwt数据集为例说明:

1
2
3
4
5
6
7
8
9
10
library(MASS)
head(birthwt)
## low age lwt race smoke ptl ht ui ftv bwt
## 85 0 19 182 2 0 0 0 1 0 2523
## 86 0 33 155 3 0 0 0 0 3 2551
## 87 0 20 105 1 1 0 0 0 1 2557
## 88 0 21 108 1 1 0 0 1 2 2594
## 89 0 18 107 1 1 0 0 1 0 2600
## 91 0 21 124 3 0 0 0 0 0 2622

此数据集中包括了婴儿出生体重及一系列导致出生体重过低的危险因子的数据。

1
2
3
ggplot(birthwt,aes(x=bwt)) +
geom_histogram(fill="white",colour="black")+
facet_grid(smoke~.)

mark

修改分面标签

上图中的分布依据是smoke,此数据只有0与1两种,因此不清楚表示什么意思,因此要进行修改,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
birthwt1 <- birthwt # 复制一份数据
birthwt1$smoke <- factor(birthwt$smoke)
levels(birthwt1$smoke)
## [1] "0" "1"
library(plyr)
birthwt1$smoke <- revalue(birthwt1$smoke,c("0"="No Smoke","1"="Smoke"))
# 替换因子的名称
ggplot(birthwt1,aes(x=bwt)) + geom_histogram(fill="white",colour="black") +
facet_grid(smoke~.)

mark

样本数目不同时的分面

默认情况下,y轴是相同的范围,但图形会不美观,如下所示:

1
2
ggplot(birthwt,aes(x=bwt)) + geom_histogram(fill="white",colour="black")+
facet_grid(race~.)

mark

分面时y轴的设置

如果scales=”free”则可以单独设定各个分面的y轴标度,但这种设制只适用于y轴标度,对x轴没有影响,x轴仍然是固定的:

1
2
3
ggplot(birthwt,aes(x=bwt))+
geom_histogram(fill="white",colour="black")+
facet_grid(race~.,scales="free")

mark

另外一种分面

1
2
3
birthwt1$smoke <- factor(birthwt1$smoke)
ggplot(birthwt1,aes(x=bwt,fill=smoke))+
geom_histogram(position="identity",alpha=0.5)

mark

position="identity"避免将数据堆积在一起,如果没有,则图形如下所示: 4

1
2
3
birthwt1$smoke <- factor(birthwt1$smoke)
ggplot(birthwt1,aes(x=bwt,fill=smoke))+
geom_histogram(alpha=0.5)

mark

绘制密度曲线图

基本绘图

用到geom_density()

1
ggplot(faithful,aes(x=waiting))+ geom_density()

mark

如果不想绘制曲线的两侧与底部:

1
2
3
ggplot(faithful,aes(x=waiting))+
geom_line(stat="density")+
expand_limits(y=0)

mark

带宽的调整

对核密度曲线进行带宽的调整,通过参数adjust来实现:

1
2
3
4
ggplot(faithful,aes(x=waiting))+
geom_line(stat="density",adjust=0.25,colour="red")+
geom_line(stat="density")+
geom_line(stat="density",adjust=2,colour="blue")

mark

手动添加x轴的范围

1
2
3
ggplot(faithful,aes(x=waiting))+
geom_density(fill="blue",alpha=0.2)+
xlim(35,105)

mark

去掉密度曲线下的横线

1
2
3
4
ggplot(faithful,aes(x=waiting))+
geom_density(fill="blue",colour="NA",alpha=0.2)+
geom_line(stat="density")+
xlim(35,105)

mark

直方图与密度曲线的叠加

1
2
3
4
5
6
ggplot(faithful,aes(x=waiting,y=..density..))+
geom_histogram(fill="cornsilk",colour="grey60",size=0.2)+
geom_density(colour="NA")+
geom_line(stat="density")+
xlim(35,105)
# geom_density(colour="NA")表示去掉密度图的最低部的直线

mark

基于分组数据绘制分组密度曲线

把变量smoke映射给colour

1
2
3
4
library(MASS)
birthwt1 <- birthwt
birthwt1$smoke <- factor(birthwt1$smoke)
ggplot(birthwt1,aes(x=bwt,colour=smoke))+geom_density()

mark

把变量smoke映射给fill

1
ggplot(birthwt1,aes(x=bwt,fill=smoke))+geom_density(alpha=0.3)

mark

分面

1
2
3
4
ggplot(birthwt1,aes(x=bwt))+
geom_density(colour="NA")+
geom_line(stat="density")+
facet_grid(smoke~.)

mark

直方图与密度曲线叠加的分面

1
2
3
ggplot(birthwt1,aes(x=bwt,y=..density..))+
geom_histogram(binwidth=200,fill="cornsilk",colour="grey60",size=0.2)+geom_density()+
facet_grid(smoke~.)

mark

绘制频数多边形

基本绘图

1
ggplot(faithful,aes(x=waiting))+geom_freqpoly()

mark

更改组距

1
ggplot(faithful,aes(x=waiting))+geom_freqpoly(binwidth=4)

mark

箱线图

基本绘图

1
ggplot(birthwt,aes(x=factor(race),y=bwt))+geom_boxplot()

mark

更改箱线图的宽度

geom_boxplot(width=0.5)参数可以更改箱子的宽度

1
ggplot(birthwt,aes(x=factor(race),y=bwt))+geom_boxplot(width=0.5)

mark

更改异常值的点

geom_boxplot(outlier.size=5,outlier.shape=21)可以更改异常值的大小与形状:

1
2
ggplot(birthwt,aes(x=factor(race),y=bwt))+
geom_boxplot(outlier.size=5,outlier.shape=22)

mark

单组箱线图的绘制

把x轴设制为1,即x轴对应的全部的数据:

1
2
3
ggplot(birthwt,aes(x=1,y=bwt))+geom_boxplot()+
scale_x_continuous(breaks=NULL)+
theme(axis.title.x=element_blank())

mark

上述命令类似于boxplot()

1
boxplot(birthwt$bwt)

mark

向箱线图添加槽口

槽口即notch,添加槽口的用处于在查看不同的中位数是否有差异。如果各箱线图的槽口互不重合,说明中位数有差异。

1
ggplot(birthwt,aes(x=factor(race),y=bwt))+geom_boxplot(notch=TRUE)

mark

上述命令会出现notch went outside hinges. Try setting notch=FALSE.这表示中间的箱子对应的槽口的上边界溢出了箱体,由于闪出的距离较小,因此在图片中基本上看不到。

向箱线图中添加均值

用到stat_summary()函数,箱线图需要注意的是,箱线图中间的线是中位数,不是均值。对于正态分布的数据,中位数与均值会比较接近,但对于偏态分布则不同。

1
2
ggplot(birthwt,aes(x=factor(race),y=bwt))+geom_boxplot()+
stat_summary(fun.y="mean",geom="point",shape=23,size=3,fill="white")

mark

绘制小提琴图

小提琴图是一种对多组数据的分布进行比较的方法,使用普通的密度曲线对多组数据进行可视化时,图中的曲线会彼此干扰,因而不宜用来对多组数据的分布进行比较,而小提琴图是并排排列的,用它对多组数据分布进行比较更容易。

基础绘图

1
2
3
library(gcookbook)
p <- ggplot(heightweight,aes(x=sex,y=heightIn))
p + geom_violin()

mark

下面是密度曲线的常规绘图:

1
ggplot(heightweight,aes(colour=sex,x=heightIn))+geom_density()

mark

小提琴图添加中位数

1
2
3
p + geom_violin() +
geom_boxplot(width=0.1,fill="black",outlier.colour=NA)+
stat_summary(fun.y=median,geom="point",fill="white",shape=21,size=2.5)

mark

保留小提琴尾部

上图中的小提琴尾部没有保留,进行了截断,可以通过trim=FALSE设置保留小提琴的尾部:

1
p + geom_violin(trim=FALSE)

mark

调节小提琴的平滑度

1
p + geom_violin(adjust=2)

如果adjust缩小,则不平滑: mark

如果adjust缩小,则不平滑:

1
p + geom_violin(adjust=0.5)

mark

绘制Wilkinson点图

Wilkinson图中点的分组和排列取决于数据,每个点的宽度对应了最大组距。系数默认的最大组距是数据范围的1/30,可以通过binwidth参数对其进行调整。

1
2
3
countries2009 <- subset(countries,Year==2009 & healthexp >2000)
p <- ggplot(countries2009,aes(x=infmortality))
p + geom_dotplot()

mark

上图中geom_dotplot()函数沿着x轴方向对数据进行分组并在y轴方向上对点进行堆积,图中各点看起来是堆积的,但受限于ggplot2的绘图设计,图形上y轴的刻度线并没有明确的含义,因此可以去掉:

去掉y轴标签的参数是scale_y_continuous(),另外 theme(axis.title.y=element_blank())主要用于移除坐标轴的标签(标签是count)。

1
2
3
p + geom_dotplot(binwidth=0.25) + geom_rug()+
scale_y_continuous(breaks=NULL)+
theme(axis.title.y=element_blank())

mark

可以通过加入参数method=”histodot”参数来设置点图的位置:

1
2
p + geom_dotplot(method="histodot",binwidth=0.25) + geom_rug()+
scale_y_continuous(breaks=NULL)+theme(axis.title.y=element_blank())

mark

中心堆叠

1
2
3
p + geom_dotplot(binwidth=0.25,stackdir = "center")+
scale_y_continuous(breaks=NULL) +
theme(axis.title.y=element_blank())

mark

基于分组数据绘制分组点图

1
2
ggplot(heightweight,aes(x=sex,y=heightIn))+
geom_dotplot(binaxis = "y",binwidht=0.5,stackdir = "center")

mark

将箱线图叠加到点图上

1
2
3
ggplot(heightweight,aes(x=sex,y=heightIn))+
geom_boxplot(outlier.colour=NA,width=0.5)+
geom_dotplot(binaxis="y",binwidth =0.5,stackdir="center",fill=NA)

mark

将箱线图放在点图旁边

1
2
3
4
ggplot(heightweight,aes(x=sex,y=heightIn))+
geom_boxplot(aes(x=as.numeric(sex)+0.2,group=sex),width=0.25)+
geom_dotplot(aes(x=as.numeric(sex)-0.2,group=sex),binaxis="y",bindwidth=0.5,stackdir="center")+
scale_x_continuous(breaks=1:nlevels(heightweight$sex),labels=levels(heightweight$sex))

mark

绘制二维数据的图

1
2
p <- ggplot(faithful,aes(x=eruptions,y=waiting))
p + geom_point()+stat_density2d()

mark

可以用..level..将密度映射给等高线的颜色:

1
p + stat_density2d(aes(colour=..level..))

mark

将高度映射为渐变

1
p + stat_density2d(aes(fill=..density..),geom="raster",contour=FALSE)

mark

将密度估计映射给瓦片颜色(tile)

1
2
p + geom_point()+
stat_density2d(aes(alpha=..density..),geom="tile",contour=FALSE)

mark

另外一种图形:

1
p + stat_density2d(aes(fill=..density..),geom="raster",contour=FALSE,h=c(0.5,5))

mark

参考资料

  1. 常肖楠, 邓一硕, 魏太云. R数据可视化手册[M]. 人民邮电出版社, 2014.